home *** CD-ROM | disk | FTP | other *** search
/ MacTech 1 to 12 / MacTech-vol-1-12.toast / Reference / FAQs on CD / C++ FAQ Lite (5⁄7) < prev    next >
Text File  |  1997-01-17  |  56KB  |  1,251 lines

  1. Archive-name: C++-faq/part5
  2. Posting-Frequency: monthly
  3. Last-modified: Jan 1, 1997
  4. URL: http://www.cerfnet.com/~mpcline/c++-faq-lite/
  5.  
  6. AUTHOR: Marshall Cline / cline@parashift.com / Paradigm Shift, Inc. /
  7. One Park St. / Norwood, NY 13668 / 315-353-6100 (voice) / 315-353-6110 (fax)
  8.  
  9. COPYRIGHT: This posting is part of "C++ FAQ Lite."  The entire "C++ FAQ Lite"
  10. document is Copyright(C) 1991-96 Marshall P. Cline, Ph.D., cline@parashift.com.
  11. All rights reserved.  Copying is permitted only under designated situations.
  12. For details, see section [1].
  13.  
  14. NO WARRANTY: THIS WORK IS PROVIDED ON AN "AS IS" BASIS.  THE AUTHOR PROVIDES NO
  15. WARRANTY WHATSOEVER, EITHER EXPRESS OR IMPLIED, REGARDING THE WORK, INCLUDING
  16. WARRANTIES WITH RESPECT TO ITS MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR
  17. PURPOSE.
  18.  
  19. C++-FAQ-Lite != C++-FAQ-Book: This document, C++ FAQ Lite, is not the same as
  20. the C++ FAQ Book.  The book (C++ FAQs, Cline and Lomow, Addison-Wesley) is 500%
  21. larger than this document, and is available in bookstores.  For details, see
  22. section [3].
  23.  
  24. ==============================================================================
  25.  
  26. SECTION [17]: Exceptions and error handling
  27.  
  28.  
  29. [17.1] How can I handle a constructor that fails?
  30.  
  31. Throw an exception.
  32.  
  33. Constructors don't have a return type, so it's not possible to use error codes.
  34. The best way to signal constructor failure is therefore to throw an exception.
  35.  
  36. If you don't have or won't use exceptions, here's a work-around.  If a
  37. constructor fails, the constructor can put the object into a "zombie" state.
  38. Do this by setting an internal status bit so the object acts sort of like its
  39. dead even though it is technically still alive.  Then add a query ("inspector")
  40. member function to check this "zombie" bit so users of your class can find out
  41. if their object is truly alive, or if it's a zombie (i.e., a "living dead"
  42. object).  Also you'll probably want to have your other member functions check
  43. this zombie bit, and, if the object isn't really alive, do a no-op (or perhaps
  44. something more obnoxious such as abort()).  This is really ugly, but it's the
  45. best you can do if you can't (or don't want to) use exceptions.
  46.  
  47. ==============================================================================
  48.  
  49. [17.2] How should I handle resources if my constructors may throw exceptions?
  50.  
  51. Every data member inside your object should clean up its own mess.
  52.  
  53. If a constructor throws an exception, the object's destructor is not run.  If
  54. your object has already done something that needs to be undone (such as
  55. allocating some memory, opening a file, or locking a semaphore), this "stuff
  56. that needs to be undone" must be remembered by a data member inside the object.
  57.  
  58. For example, rather than allocating memory into a raw Fred* data member, put
  59. the allocated memory into a "smart pointer" member object, and the destructor
  60. of this smart pointer will delete the Fred object when the smart pointer dies.
  61. The standard class auto_ptr is an example of such as "smart pointer" class.
  62. You can also write your own reference counting smart pointer[16.19].  You can
  63. also use smart pointers to "point" to disk records or objects on other
  64. machines[13.3].
  65.  
  66. ==============================================================================
  67.  
  68. [17.3] How do I change the string-length of an array of char to prevent memory
  69.        leaks even if/when someone throws an exception?
  70.  
  71. If what you really want to do is work with strings, don't use an array of char
  72. in the first place, since arrays are evil[21.5].  Instead use an object of some
  73. string-like class.
  74.  
  75. For example, suppose you want to get a copy of a string, fiddle with the copy,
  76. then append another string to the end of the fiddled copy.  The array-of-char
  77. approach would look something like this:
  78.  
  79.     void userCode(const char* s1, const char* s2)
  80.     {
  81.       // Get a copy of s1 into a new string called copy:
  82.       char* copy = new char[strlen(s1) + 1];
  83.       strcpy(copy, s1);
  84.  
  85.       // Now that we have a local pointer to freestore-allocated memory,
  86.       // we need to use a try block to prevent memory leaks:
  87.       try {
  88.  
  89.         // Now we fiddle with copy for a while...
  90.         // ...
  91.  
  92.         // Later we want to append s2 onto the fiddled-with copy:
  93.         // ... [Here's where people want to reallocate copy] ...
  94.         char* copy2 = new char[strlen(copy) + strlen(s2) + 1];
  95.         strcpy(copy2, copy);
  96.         strcpy(copy2 + strlen(copy), s2);
  97.         delete[] copy;
  98.         copy = copy2;
  99.  
  100.         // Finally we fiddle with copy again...
  101.         // ...
  102.  
  103.       } catch (...) {
  104.         delete[] copy;   // Prevent memory leaks if we got an exception
  105.         throw;           // Re-throw the current exception
  106.       }
  107.  
  108.       delete[] copy;     // Prevent memory leaks if we did NOT get an exception
  109.     }
  110.  
  111. Using char*s like this is tedious and error prone.  Why not just use an object
  112. of some string class? Your compiler probably supplies a string-like class, and
  113. it's probably just as fast and certainly it's a lot simpler and safer than the
  114. char* code that you would have to write yourself.  For example, if you're using
  115. the string class from the standardization committee[6.12], your code might look
  116. something like this:
  117.  
  118.     #include <string>           // Let the compiler see class string
  119.     using namespace std;
  120.  
  121.     void userCode(const string& s1, const string& s2)
  122.     {
  123.       // Get a copy of s1 into a new string called copy:
  124.       string copy = s1;         // NOTE: we do NOT need a try block!
  125.  
  126.       // Now we fiddle with copy for a while...
  127.       // ...
  128.  
  129.       // Later we want to append s2 onto the fiddled-with copy:
  130.       copy += s2;               // NOTE: we do NOT need to reallocate memory!
  131.  
  132.       // Finally we fiddle with copy again...
  133.       // ...
  134.     }                           // NOTE: we do NOT need to delete[] anything!
  135.  
  136. ==============================================================================
  137.  
  138. SECTION [18]: Const correctness
  139.  
  140.  
  141. [18.1] What is "const correctness"? [UPDATED!]
  142.  
  143. [Recently rewrote because of helpful feedback from Nor Jaidi (on 1/97).]
  144.  
  145. A good thing.  It means using the keyword const to prevent const objects from
  146. getting mutated.
  147.  
  148. For example, if you wanted to create a function f() that accepted a String,
  149. plus you want to promise callers not to change the caller's String that gets
  150. passed to f(), you can have f() receive its String parameter . . .
  151.  * void f1(const String& s);      // Pass by reference-to-const
  152.  * void f2(const String* sptr);   // Pass by pointer-to-const
  153.  * void f3(String s);             // Pass by value
  154.  
  155. In the pass by reference-to-const and pass by pointer-to-const cases, any
  156. attempts to change to the caller's String within the f() functions would be
  157. flagged by the compiler as an error at compile-time.  This check is done
  158. entirely at compile-time: there is no run-time space or speed cost for the
  159. const.  In the pass by value case (f3()), the called function gets a copy of
  160. the caller's String.  This means that f3() can change its local copy, but the
  161. copy is destroyed when f3() returns.  In particular f3() cannot change the
  162. caller's String object.
  163.  
  164. As an opposite example, if you wanted to create a function g() that accepted a
  165. String, but you want to let callers know that g() might change the caller's
  166. String object.  In this case you can have g() receive its String parameter . .
  167. .
  168.  * void g1(String& s);      // Pass by reference-to-non-const
  169.  * void g2(String* sptr);   // Pass by pointer-to-non-const
  170.  
  171. The lack of const in these functions tells the compiler that they are allowed
  172. to (but are not required to) change the caller's String object.  Thus they can
  173. pass their String to any of the f() functions, but only f3() (the one that
  174. receives its parameter "by value") can pass its String to g1() or g2().  If
  175. f1() or f2() need to call either g() function, a local copy of the String
  176. object must be passed to the g() function; the parameter to f1() or f2() cannot
  177. be directly passed to either g() function.  E.g.,
  178.  
  179.     void g1(String& s);
  180.  
  181.     void f1(const String& s)
  182.     {
  183.       g1(s);          // Compile-time Error since s is const
  184.  
  185.       String localCopy = s;
  186.       g1(localCopy);  // OK since localCopy is not const
  187.     }
  188.  
  189. Naturally in the above case, any changes that g1() makes are made to the
  190. localCopy object that is local to f1().  In particular, no changes will be made
  191. to the const parameter that was passed by reference to f1().
  192.  
  193. ==============================================================================
  194.  
  195. [18.2] How is "const correctness" related to ordinary type safety?
  196.  
  197. Declaring the const-ness of a parameter is just another form of type safety.
  198. It is almost as if a const String, for example, is a different class than an
  199. ordinary String, since the const variant is missing the various mutative
  200. operations in the non-const variant (e.g., you can imagine that a const String
  201. simply doesn't have an assignment operator).
  202.  
  203. If you find ordinary type safety helps you get systems correct (it does;
  204. especially in large systems), you'll find const correctness helps also.
  205.  
  206. ==============================================================================
  207.  
  208. [18.3] Should I try to get things const correct "sooner" or "later"?
  209.  
  210. At the very, very, very beginning.
  211.  
  212. Back-patching const correctness results in a snowball effect: every const you
  213. add "over here" requires four more to be added "over there."
  214.  
  215. ==============================================================================
  216.  
  217. [18.4] What does "const Fred* p" mean?
  218.  
  219. It means p points to an object of class Fred, but p can't be used to change
  220. that Fred object (naturally p could also be NULL).
  221.  
  222. For example, if class Fred has a const member function[18.9] called inspect(),
  223. saying p->inspect() is OK.  But if class Fred has a non-const member
  224. function[18.9] called mutate(), saying p->mutate() is an error (the error is
  225. caught by the compiler; no run-time tests are done, which means const doesn't
  226. slow your program down).
  227.  
  228. ==============================================================================
  229.  
  230. [18.5] What's the difference between "const Fred* p", "Fred* const p" and
  231.        "const Fred* const p"?
  232.  
  233. You have to read pointer declarations right-to-left.
  234.  * const Fred* p means "p points to a Fred that is const" -- that is, the Fred
  235.    object can't be changed via p[18.13].
  236.  * Fred* const p means "p is a const pointer to a Fred" -- that is, you can
  237.    change the Fred object via p[18.13], but you can't change the pointer p
  238.    itself.
  239.  * const Fred* const p means "p is a const pointer to a const Fred" -- that is,
  240.    you can't change the pointer p itself, nor can you change the Fred object
  241.    via p[18.13].
  242.  
  243. ==============================================================================
  244.  
  245. [18.6] What does "const Fred& x" mean?
  246.  
  247. It means x aliases a Fred object, but x can't be used to change that Fred
  248. object.
  249.  
  250. For example, if class Fred has a const member function[18.9] called inspect(),
  251. saying x.inspect() is OK.  But if class Fred has a non-const member
  252. function[18.9] called mutate(), saying x.mutate() is an error (the error is
  253. caught by the compiler; no run-time tests are done, which means const doesn't
  254. slow your program down).
  255.  
  256. ==============================================================================
  257.  
  258. [18.7] Does "Fred& const x" make any sense?
  259.  
  260. No, it is nonsense.
  261.  
  262. To find out what the above declaration means, you have to read it
  263. right-to-left[18.5].  Thus "Fred& const x" means "x is a const reference to a
  264. Fred".  But that is redundant, since references are always const.  You can't
  265. reseat a reference[8.4].  Never.  With or without the const.
  266.  
  267. In other words, "Fred& const x" is functionally equivalent to "Fred& x".  Since
  268. you're gaining nothing by adding the const after the &, you shouldn't add it
  269. since it will confuse people.  I.e., the const will make some people think that
  270. the Fred is const, as if you had said "const Fred& x".
  271.  
  272. ==============================================================================
  273.  
  274. [18.8] What does "Fred const& x" mean?
  275.  
  276. "Fred const& x" is functionally equivalent to "const Fred& x"[18.6].
  277.  
  278. The problem with using "Fred const& x" (with the const before the &) is that it
  279. could easily be mis-typed as the nonsensical "Fred &const x"[18.7] (with the
  280. const after the &).
  281.  
  282. Better to simply use const Fred& x.
  283.  
  284. ==============================================================================
  285.  
  286. [18.9] What is a "const member function"?
  287.  
  288. A member function that inspects (rather than mutates) its object.
  289.  
  290. A const member function is indicated by a const suffix just after the member
  291. function's parameter list.  Member functions with a const suffix are called
  292. "const member functions" or "inspectors." Member functions without a const
  293. suffix are called "non-const member functions" or "mutators."
  294.  
  295.     class Fred {
  296.     public:
  297.       void inspect() const;   // This member promises NOT to change *this
  298.       void mutate();          // This member function might change *this
  299.     };
  300.  
  301.     void userCode(Fred& changeable, const Fred& unchangeable)
  302.     {
  303.       changeable.inspect();   // OK: doesn't change a changeable object
  304.       changeable.mutate();    // OK: changes a changeable object
  305.  
  306.       unchangeable.inspect(); // OK: doesn't change an unchangeable object
  307.       unchangeable.mutate();  // ERROR: attempt to change unchangeable object
  308.     }
  309.  
  310. The error in unchangeable.mutate() is caught at compile time.  There is no
  311. runtime space or speed penalty for const.
  312.  
  313. The trailing const on inspect() member function means that the abstract
  314. (client-visible) state of the object isn't going to change.  This is slightly
  315. different from promising that the "raw bits" of the object's struct aren't
  316. going to change.  C++ compilers aren't allowed to take the "bitwise"
  317. interpretation unless they can solve the aliasing problem, which normally can't
  318. be solved (i.e., a non-const alias could exist which could modify the state of
  319. the object).  Another (important) insight from this aliasing issue: pointing at
  320. an object with a const pointer doesn't guarantee that the object won't change;
  321. it promises only that the object won't change via that pointer).
  322.  
  323. ==============================================================================
  324.  
  325. [18.10] What do I do if I want to update an "invisible" data member inside a
  326.         const member function?
  327.  
  328. Use mutable, or use const_cast.
  329.  
  330. A small percentage of inspectors need to make innocuous changes to data members
  331. (e.g., a Set object might want to cache its last lookup in hopes of improving
  332. the performance of its next lookup).  By saying the changes are "innocuous," I
  333. mean that the changes wouldn't be visible from outside the object's interface
  334. (otherwise the member function would be a mutator rather than an inspector).
  335.  
  336. When this happens, the data member which will be modified should be marked as
  337. mutable (put the mutable keyword just before the data member's declaration;
  338. i.e., in the same place where you could put const).  This tells the compiler
  339. that the data member is allowed to change during a const member function.  If
  340. your compiler doesn't support the mutable keyword, you can cast away the
  341. const'ness of this via the const_cast keyword.  E.g., in Set::lookup() const,
  342. you might say,
  343.  
  344.     Set* self = const_cast<Set*>(this);
  345.  
  346. After this line, self will have the same bits as this (e.g., self == this), but
  347. self is a Set* rather than a const Set*.  Therefore you can use self to modify
  348. the object pointed to by this.
  349.  
  350. ==============================================================================
  351.  
  352. [18.11] Does const_cast mean lost optimization opportunities?
  353.  
  354. In theory, yes; in practice, no.
  355.  
  356. Even if the language outlawed const_cast, the only way to avoid flushing the
  357. register cache across a const member function call would be to solve the
  358. aliasing problem (i.e., to prove that there are no non-const pointers that
  359. point to the object).  This can happen only in rare cases (when the object is
  360. constructed in the scope of the const member function invocation, and when all
  361. the non-const member function invocations between the object's construction and
  362. the const member function invocation are statically bound, and when every one
  363. of these invocations is also inlined, and when the constructor itself is
  364. inlined, and when any member functions the constructor calls are inline).
  365.  
  366. ==============================================================================
  367.  
  368. [18.12] Why does the compiler allow me to change an int after I've pointed at
  369.         it with a const int*?
  370.  
  371. Because "const int* p" means "p promises not to change the *p," not "*p
  372. promises not to change."
  373.  
  374. Causing a const int* to point to an int doesn't const-ify the int.  The int
  375. can't be changed via the const int*, but if someone else has a int* (note: no
  376. const) that points to ("aliases") the same int, then that int* can be used to
  377. change the int.  For example:
  378.  
  379.     void f(const int* p1, int* p2)
  380.     {
  381.       int i = *p1;         // Get the (original) value of *p1
  382.       *p2 = 7;             // If p1 == p2, this will also change *p1
  383.       int j = *p1;         // Get the (possibly new) value of *p1
  384.       if (i != j) {
  385.         cout << "*p1 changed, but it didn't change via pointer p1!\n";
  386.         assert(p1 == p2);  // This is the only way *p1 could be different
  387.       }
  388.     }
  389.  
  390.     main()
  391.     {
  392.       int x;
  393.       f(&x, &x);           // This is perfectly legal (and even moral!)
  394.     }
  395.  
  396. Note that main() and f(const int*,int*) could be in different compilation units
  397. that are compiled on different days of the week.  In that case there is no way
  398. the compiler can possibly detect the aliasing at compile time.  Therefore there
  399. is no way we could make a language rule that prohibits this sort of thing.  In
  400. fact, we wouldn't even want to make such a rule, since in general it's
  401. considered a feature that you can have many pointers pointing to the same
  402. thing.  The fact that one of those pointers promises not to change the
  403. underlying "thing" is just a promise made by the pointer; it's not a promise
  404. made by the "thing".
  405.  
  406. ==============================================================================
  407.  
  408. [18.13] Does "const Fred* p" mean that *p can't change?
  409.  
  410. No! (This is related to the FAQ about aliasing of int pointers[18.12].)
  411.  
  412. "const Fred* p" means that the Fred can't be changed via pointer p, but any
  413. aliasing pointers that aren't const can be used to change the Fred object.  For
  414. example, if you have two pointers "const Fred* p" and "Fred* q" that point to
  415. the same Fred object (aliasing), pointer q can be used to change the Fred
  416. object but pointer p cannot.
  417.  
  418.     class Fred {
  419.     public:
  420.       void inspect() const;   // A const member function[18.9]
  421.       void mutate();          // A non-const member function[18.9]
  422.     };
  423.  
  424.     main()
  425.     {
  426.       Fred f;
  427.       const Fred* p = &f;
  428.             Fred* q = &f;
  429.  
  430.       p->insepct();    // OK: No change to *p
  431.       p->mutate();     // Error: Can't change *p via p
  432.  
  433.       q->inspect();    // OK: q is allowed to inspect the object
  434.       q->mutate();     // OK: q is allowed to mutate the object
  435.     }
  436.  
  437. ==============================================================================
  438.  
  439. SECTION [19]: Inheritance -- basics
  440.  
  441.  
  442. [19.1] Is inheritance important to C++?
  443.  
  444. Yep.
  445.  
  446. Inheritance is what separates abstract data type (ADT) programming from OO
  447. programming.
  448.  
  449. ==============================================================================
  450.  
  451. [19.2] When would I use inheritance?
  452.  
  453. As a specification device.
  454.  
  455. Human beings abstract things on two dimensions: part-of and kind-of.  A Ford
  456. Taurus is-a-kind-of-a Car, and a Ford Taurus has-a Engine, Tires, etc.  The
  457. part-of hierarchy has been a part of software since the ADT style became
  458. relevant; inheritance adds "the other" major dimension of decomposition.
  459.  
  460. ==============================================================================
  461.  
  462. [19.3] How do you express inheritance in C++?
  463.  
  464. By the : public syntax:
  465.  
  466.     class Car : public Vehicle {
  467.     public:
  468.       // ...
  469.     };
  470.  
  471. We state the above relationship in several ways:
  472.  * Car is "a kind of a" Vehicle
  473.  * Car is "derived from" Vehicle
  474.  * Car is "a specialized" Vehicle
  475.  * Car is the "subclass" of Vehicle
  476.  * Vehicle is the "base class" of Car
  477.  * Vehicle is the "superclass" of Car (this not as common in the C++ community)
  478.  
  479. (Note: this FAQ has to do with public inheritance; private and protected
  480. inheritance[24] are different.)
  481.  
  482. ==============================================================================
  483.  
  484. [19.4] Is it OK to convert a pointer from a derived class to its base class?
  485.  
  486. Yes.
  487.  
  488. An object of a derived class is a kind of the base class.  Therefore the
  489. conversion from a derived class pointer to a base class pointer is perfectly
  490. safe, and happens all the time.  For example, if I am pointing at a car, I am
  491. in fact pointing at a vehicle, so converting a Car* to a Vehicle* is perfectly
  492. safe and normal:
  493.  
  494.     void f(Vehicle* v);
  495.     void g(Car* c) { f(c); }  // Perfectly safe; no cast
  496.  
  497. (Note: this FAQ has to do with public inheritance; private and protected
  498. inheritance[24] are different.)
  499.  
  500. ==============================================================================
  501.  
  502. [19.5] What's the difference between public:, private:, and protected:?
  503.  
  504.  * A member (either data member or member function) declared in a private:
  505.    section of a class can only be accessed by member functions and friends[14]
  506.    of that class
  507.  * A member (either data member or member function) declared in a protected:
  508.    section of a class can only be accessed by member functions and friends[14]
  509.    of that class, and by member functions and friends[14] of derived classes
  510.  * A member (either data member or member function) declared in a public:
  511.    section of a class can be accessed by anyone
  512.  
  513. ==============================================================================
  514.  
  515. [19.6] Why can't my derived class access private: things from my base class?
  516.  
  517. To protect you from future changes to the base class.
  518.  
  519. Derived classes do not get access to private members of a base class.  This
  520. effectively "seals off" the derived class from any changes made to the private
  521. members of the base class.
  522.  
  523. ==============================================================================
  524.  
  525. [19.7] How can I protect subclasses from breaking when I change internal parts?
  526.  
  527. A class has two distinct interfaces for two distinct sets of clients:
  528.  * It has a public: interface that serves unrelated classes
  529.  * It has a protected: interface that serves derived classes
  530.  
  531. Unless you expect all your subclasses to be built by your own team, you should
  532. consider making your base class's bits be private:, and use protected: inline
  533. access functions by which derived classes will access the private data in the
  534. base class.  This way the private bits can change, but the derived class's code
  535. won't break unless you change the protected access functions.
  536.  
  537. ==============================================================================
  538.  
  539. SECTION [20]: Inheritance -- virtual functions
  540.  
  541.  
  542. [20.1] What is a "virtual member function"?
  543.  
  544. From an OO perspective, it is the single most important feature of C++: [6.8],
  545. [6.9].
  546.  
  547. A virtual function allows derived classes to replace the implementation
  548. provided by the base class.  The compiler makes sure the replacement is always
  549. called whenever the object in question is actually of the derived class, even
  550. if the object is accessed by a base pointer rather than a derived pointer.
  551. This allows algorithms in the base class to be replaced in the derived class,
  552. even if users don't know about the derived class.
  553.  
  554. The derived class can either fully replace ("override") the base class member
  555. function, or the derived class can partially replace ("augment") the base class
  556. member function.  The latter is accomplished by having the derived class member
  557. function call the base class member function, if desired.
  558.  
  559. ==============================================================================
  560.  
  561. [20.2] How can C++ achieve dynamic binding yet also static typing?
  562.  
  563. When you have a pointer to an object, the object may actually be of a class
  564. that is derived from the class of the pointer (e.g., a Vehicle* that is
  565. actually pointing to a Car object).  Thus there are two types: the (static)
  566. type of the pointer (Vehicle, in this case), and the (dynamic) type of the
  567. pointed-to object (Car, in this case).
  568.  
  569. Static typing means that the legality of a member function invocation is
  570. checked at the earliest possible moment: by the compiler at compile time.  The
  571. compiler uses the static type of the pointer to determine whether the member
  572. function invocation is legal.  If the type of the pointer can handle the member
  573. function, certainly the pointed-to object can handle it as well.  E.g., if
  574. Vehicle has a certain member function, certainly Car also has that member
  575. function since Car is a kind-of Vehicle.
  576.  
  577. Dynamic binding means that the address of the code in a member function
  578. invocation is determined at the last possible moment: based on the dynamic type
  579. of the object at run time.  It is called "dynamic binding" because the binding
  580. to the code that actually gets called is accomplished dynamically (at run
  581. time).  Dynamic binding is a result of virtual functions.
  582.  
  583. ==============================================================================
  584.  
  585. [20.3] What's the difference between how virtual and non-virtual member
  586.        functions are called? [NEW!]
  587.  
  588. [Recently created (on 11/96).]
  589.  
  590. Non-virtual member functions are resolved statically.  That is, the member
  591. function is selected statically (at compile-time) based on the type of the
  592. pointer (or reference) to the object.
  593.  
  594. In contrast, virtual member functions are resolved dynamically (at run-time).
  595. That is, the member function is selected dynamically (at run-time) based on the
  596. type of the object, not the type of the pointer/reference to that object.  This
  597. is called "dynamic binding." Most compilers use some variant of the following
  598. technique: if the object has one or more virtual functions, the compiler puts a
  599. hidden pointer in the object called a "virtual-pointer" or "v-pointer." This
  600. v-pointer points to a global table called the "virtual-table" or "v-table."
  601.  
  602. The compiler creates a v-table for each class that has at least one virtual
  603. function.  For example, if class Circle has virtual functions for draw() and
  604. move() and resize(), there would be exactly one v-table associated with class
  605. Circle, even if there were a gazillion Circle objects, and the v-pointer of
  606. each of those Circle objects would point to the Circle v-table.  The v-table
  607. itself has pointers to each of the virtual functions in the class.  For
  608. example, the Circle v-table would have three pointers: a pointer to
  609. Circle::draw(), a pointer to Circle::move(), and a pointer to Circle::resize().
  610.  
  611. During a dispatch of a virtual function, the run-time system follows the
  612. object's v-pointer to the class's v-table, then follows the appropriate slot in
  613. the v-table to the method code.
  614.  
  615. The space-cost overhead of the above technique is nominal: an extra pointer per
  616. object (but only for objects that will need to do dynamic binding), plus an
  617. extra pointer per method (but only for virtual methods).  The time-cost
  618. overhead is also fairly nominal: compared to a normal function call, a virtual
  619. function call requires two extra fetches (one to get the value of the
  620. v-pointer, a second to get the address of the method).  None of this runtime
  621. activity happens with non-virtual functions, since the compiler resolves
  622. non-virtual functions exclusively at compile-time based on the type of the
  623. pointer.
  624.  
  625. Note: the above discussion is simplified considerably, since it doesn't account
  626. for extra structural things like multiple inheritance, virtual inheritance,
  627. RTTI, etc., nor does it account for space/speed issues such as page faults,
  628. calling a function via a pointer-to-function, etc.  If you want to know about
  629. those other things, please ask comp.lang.c++; PLEASE DO NOT SEND E-MAIL TO ME!
  630.  
  631. ==============================================================================
  632.  
  633. [20.4] When should my destructor be virtual?
  634.  
  635. When you may delete a derived object via a base pointer.
  636.  
  637. virtual functions bind to the code associated with the class of the object,
  638. rather than with the class of the pointer/reference.  When you say
  639. delete basePtr, and the base class has a virtual destructor, the destructor
  640. that gets invoked is the one associated with the type of the object *basePtr,
  641. rather than the one associated with the type of the pointer.  This is generally
  642. A Good Thing.
  643.  
  644. TECHNO-GEEK WARNING; PUT YOUR PROPELLER HAT ON.
  645. Technically speaking, you need a base class's destructor to be virtual if and
  646. only if you intend to allow someone to invoke an object's destructor via a base
  647. class pointer (this is normally done implicitly via delete), and the object
  648. being destructed is of a derived class that has a non-trivial destructor.  A
  649. class has a non-trivial destructor if it either has an explicit destructor, or
  650. if it has a member object or a base class that has a non-trivial destructor
  651. (note that this is a recursive definition (e.g., a class has a non-trivial
  652. destructor if it has a member object (which has a base class (which has a
  653. member object (which has a base class (which has an explicit destructor)))))).
  654. END TECHNO-GEEK WARNING; REMOVE YOUR PROPELLER HAT
  655.  
  656. If you had a hard grokking the previous rule, try this (over)simplified one on
  657. for size: A class should have a virtual destructor unless that class has no
  658. virtual functions.  Rationale: if you have any virtual functions at all, you're
  659. probably going to be doing "stuff" to derived objects via a base pointer, and
  660. some of the "stuff" you may do may include invoking a destructor (normally done
  661. implicitly via delete).  Plus once you've put the first virtual function into a
  662. class, you've already paid all the per-object space cost that you'll ever pay
  663. (one pointer per object; note that this is theoretically compiler-specific; in
  664. practice everyone does it pretty much the same way), so making the destructor
  665. virtual won't generally cost you anything extra.
  666.  
  667. ==============================================================================
  668.  
  669. [20.5] What is a "virtual constructor"?
  670.  
  671. An idiom that allows you to do something that C++ doesn't directly support.
  672.  
  673. You can get the effect of a virtual constructor by a virtual clone() member
  674. function (for copy constructing), or a virtual create() member function (for
  675. the default constructor[10.4]).
  676.  
  677.     class Shape {
  678.     public:
  679.       virtual ~Shape() { }                 // A virtual destructor[20.4]
  680.       virtual void draw() = 0;             // A pure virtual function[22.4]
  681.       virtual void move() = 0;
  682.       // ...
  683.       virtual Shape* clone()  const = 0;   // Uses the copy constructor
  684.       virtual Shape* create() const = 0;   // Uses the default constructor[10.4]
  685.     };
  686.  
  687.     class Circle : public Shape {
  688.     public:
  689.       Circle* clone()  const { return new Circle(*this); }
  690.       Circle* create() const { return new Circle();      }
  691.       // ...
  692.     };
  693.  
  694. In the clone() member function, the new Circle(*this) code calls Circle's copy
  695. constructor to copy the state of this into the newly created Circle object.  In
  696. the create() member function, the new Circle() code calls Circle's default
  697. constructor[10.4].
  698.  
  699. Users use these as if they were "virtual constructors":
  700.  
  701.     void userCode(Shape& s)
  702.     {
  703.       Shape* s2 = s.clone();
  704.       Shape* s3 = s.create();
  705.       // ...
  706.       delete s2;    // You probably need a virtual destructor[20.4] here
  707.       delete s3;
  708.     }
  709.  
  710. This function will work correctly regardless of whether the Shape is a Circle,
  711. Square, or some other kind-of Shape that doesn't even exist yet.
  712.  
  713. ==============================================================================
  714.  
  715. SECTION [21]: Inheritance -- proper inheritance and substitutability
  716.  
  717.  
  718. [21.1] Should I hide member functions that were public in my base class?
  719.  
  720. Never, never, never do this.  Never.  Never!
  721.  
  722. Attempting to hide (eliminate, revoke, privatize) inherited public member
  723. functions is an all-too-common design error.  It usually stems from muddy
  724. thinking.
  725.  
  726. (Note: this FAQ has to do with public inheritance; private and protected
  727. inheritance[24] are different.)
  728.  
  729. ==============================================================================
  730.  
  731. [21.2] Derived* --> Base* works OK; why doesn't Derived** --> Base** work?
  732.  
  733. C++ allows a Derived* to be converted to a Base*, since a Derived object is a
  734. kind of a Base object.  However trying to convert a Derived** to a Base** is
  735. flagged as an error.  Although this error may not be obvious, it is nonetheless
  736. a good thing.  For example, if you could convert a Car** to a Vehicle**, and if
  737. you could similarly convert a NuclearSubmarine** to a Vehicle**, you could
  738. assign those two pointers and end up making a Car* point at a NuclearSubmarine:
  739.  
  740.     class Vehicle                           { /*...*/ };
  741.     class Car              : public Vehicle { /*...*/ };
  742.     class NuclearSubmarine : public Vehicle { /*...*/ };
  743.  
  744.     main()
  745.     {
  746.       Car   car;
  747.       Car*  carPtr = &car;
  748.       Car** carPtrPtr = &carPtr;
  749.       Vehicle** vehiclePtrPtr = carPtrPtr;  // This is an error in C++
  750.       NuclearSubmarine  sub;
  751.       NuclearSubmarine* subPtr = ⊂
  752.       *vehiclePtrPtr = subPtr;
  753.       // This last line would have caused carPtr to point to sub !
  754.     }
  755.  
  756. In other words, if it was legal to convert a Derived** to a Base**, the Base**
  757. could be dereferenced (yielding a Base*), and the Base* could be made to point
  758. to an object of a different derived class, which could cause serious problems
  759. for national security (who knows what would happen if you invoked the
  760. openGasCap() member function on what you thought was a Car, but in reality it
  761. was a NuclearSubmarine!!)..
  762.  
  763. (Note: this FAQ has to do with public inheritance; private and protected
  764. inheritance[24] are different.)
  765.  
  766. ==============================================================================
  767.  
  768. [21.3] Is a parking-lot-of-Car a kind-of parking-lot-of-Vehicle?
  769.  
  770. Nope.
  771.  
  772. I know it sounds strange, but it's true.  You can think of this as a direct
  773. consequence of the previous FAQ, or you can reason it this way: if the kind-of
  774. relationship were valid, then someone could point a parking-lot-of-Vehicle
  775. pointer at a parking-lot-of-Car.  But parking-lot-of-Vehicle has a
  776. addNewVehicleToParkingLot(Vehicle&) member function which can add any Vehicle
  777. object to the parking lot.  This would allow you to park a NuclearSubmarine in
  778. a parking-lot-of-Car.  Certainly it would be surprising if someone removed what
  779. they thought was a Car from the parking-lot-of-Car, only to find that it is
  780. actually a NuclearSubmarine.
  781.  
  782. Another way to say this truth: a container of Thing is not a kind-of container
  783. of Anything even if a Thing is a kind-of an Anything.  Swallow hard; it's true.
  784.  
  785. You don't have to like it.  But you do have to accept it.
  786.  
  787. One last example which we use in our OO/C++ training courses: "A Bag-of-Apple
  788. is not a kind-of Bag-of-Fruit." If a Bag-of-Apple could be passed as a
  789. Bag-of-Fruit, someone could put a Banana into the Bag, even though it is
  790. supposed to only contain Apples!
  791.  
  792. (Note: this FAQ has to do with public inheritance; private and protected
  793. inheritance[24] are different.)
  794.  
  795. ==============================================================================
  796.  
  797. [21.4] Is an array of Derived a kind-of array of Base?
  798.  
  799. Nope.
  800.  
  801. This is a corollary of the previous FAQ.  Unfortunately this one can get you
  802. into a lot of hot water.  Consider this:
  803.  
  804.     class Base {
  805.     public:
  806.       virtual void f();             // 1
  807.     };
  808.  
  809.     class Derived : public Base {
  810.     public:
  811.       // ...
  812.     private:
  813.       int i_;                       // 2
  814.     };
  815.  
  816.     void userCode(Base* arrayOfBase)
  817.     {
  818.       arrayOfBase[1].f();           // 3
  819.     }
  820.  
  821.     main()
  822.     {
  823.       Derived arrayOfDerived[10];   // 4
  824.       userCode(arrayOfDerived);     // 5
  825.     }
  826.  
  827. The compiler thinks this is perfectly type-safe.  Line 5 converts a Derived* to
  828. a Base*.  But in reality it is horrendously evil: since Derived is larger than
  829. Base, the pointer arithmetic done on line 3 is incorrect: the compiler uses
  830. sizeof(Base) when computing the address for arrayOfBase[1], yet the array is an
  831. array of Derived, which means the address computed on line 3 (and the
  832. subsequent invocation of member function f()) isn't even at the beginning of
  833. any object! It's smack in the middle of a Derived object.  Assuming your
  834. compiler uses the usual approach to virtual[20] functions, this will
  835. reinterpret the int i_ of the first Derived as if it pointed to a virtual
  836. table, it will follow that "pointer" (which at this point means we're digging
  837. stuff out of a random memory location), and grab one of the first few words of
  838. memory at that location and interpret them as if they were the address of a C++
  839. member function, then load that (random memory location) into the instruction
  840. pointer and begin grabbing machine instructions from that memory location.  The
  841. chances of this crashing are very high.
  842.  
  843. The root problem is that C++ can't distinguish between a pointer-to-a-thing and
  844. a pointer-to-an-array-of-things.  Naturally C++ "inherited" this feature from
  845. C.
  846.  
  847. NOTE: If we had used an array-like class (e.g., vector<Derived> from STL[32.1])
  848. instead of using a raw array, this problem would have been properly trapped as
  849. an error at compile time rather than a run-time disaster.
  850.  
  851. (Note: this FAQ has to do with public inheritance; private and protected
  852. inheritance[24] are different.)
  853.  
  854. ==============================================================================
  855.  
  856. [21.5] Does array-of-Derived is-not-a-kind-of array-of-Base mean arrays are
  857.        bad?
  858.  
  859. Yes, arrays are evil.  (only half kidding).
  860.  
  861. Seriously, arrays are very closely related to pointers, and pointers are
  862. notoriously difficult to deal with.  But if you have a complete grasp of why
  863. the above few FAQs were a problem from a design perspective (e.g., if you
  864. really know why a container of Thing is not a kind-of container of Anything),
  865. and if you think everyone else who will be maintaining your code also has a
  866. full grasp on these OO design truths, then you should feel free to use arrays.
  867. But if you're like most people, you should use a template container class such
  868. as vector<T> from STL[32.1] rather than raw arrays.
  869.  
  870. (Note: this FAQ has to do with public inheritance; private and protected
  871. inheritance[24] are different.)
  872.  
  873. ==============================================================================
  874.  
  875. [21.6] Is a Circle a kind-of an Ellipse? [UPDATED!]
  876.  
  877. [Recently added a caveat that setSize(x,y) isn't sacred (on 1/97).]
  878.  
  879. Not if Ellipse promises to be able to change its size asymmetrically.
  880.  
  881. For example, suppose Ellipse has a setSize(x,y) member function, and suppose
  882. this member function promises the Ellipse's width() will be x, and its height()
  883. will be y.  In this case, Circle can't be a kind-of Ellipse.  Simply put, if
  884. Ellipse can do something Circle can't, then Circle can't be a kind of Ellipse.
  885.  
  886. This leaves two potential (valid) relationships between Circle and Ellipse:
  887.  * Make Circle and Ellipse completely unrelated classes
  888.  * Derive Circle and Ellipse from a base class representing "Ellipses that
  889.    can't necessarily perform an unequal-setSize() operation"
  890.  
  891. In the first case, Ellipse could be derived from class AsymmetricShape, and
  892. setSize(x,y) could be introduced in AsymmetricShape.  However Circle could be
  893. derived from SymmetricShape which has a setSize(size) member function.
  894.  
  895. In the second case, class Oval could only have setSize(size) which sets both
  896. the width() and the height() to size.  Ellipse and Circle could both inherit
  897. from Oval.  Ellipse --but not Circle-- could add the setSize(x,y) operation
  898. (but beware of the hiding rule[23.3] if the same member function name setSize()
  899. is used for both operations).
  900.  
  901. (Note: this FAQ has to do with public inheritance; private and protected
  902. inheritance[24] are different.)
  903.  
  904. (Note: setSize(x,y) isn't sacred.  Depending on your goals, it may be okay to
  905. prevent users from changing the dimensions of an Ellipse, in which case it
  906. would be a valid design choice to not have a setSize(x,y) method in Ellipse.
  907. However this series of FAQs discusses what to do when you want to create a
  908. derived class of a pre-existing base class that has an "unacceptable" method in
  909. it.  Of course the ideal situation is to discover this problem when the base
  910. class doesn't yet exist.  But life isn't always ideal...)
  911.  
  912. ==============================================================================
  913.  
  914. [21.7] Are there other options to the "Circle is/isnot kind-of Ellipse"
  915.        dilemma? [UPDATED!]
  916.  
  917. [Recently added a caveat that setSize(x,y) isn't sacred (on 1/97).]
  918.  
  919. If you claim that all Ellipses can be squashed asymmetrically, and you claim
  920. that Circle is a kind-of Ellipse, and you claim that Circle can't be squashed
  921. asymmetrically, clearly you've got to adjust (revoke, actually) one of your
  922. claims.  Thus you've either got to get rid of Ellipse::setSize(x,y), get rid of
  923. the inheritance relationship between Circle and Ellipse, or admit that your
  924. Circles aren't necessarily circular.
  925.  
  926. Here are the two most common traps new OO/C++ programmers regularly fall into.
  927. They attempt to use coding hacks to cover up a broken design (they redefine
  928. Circle::setSize(x,y) to throw an exception, call abort(), choose the average of
  929. the two parameters, or to be a no-op).  Unfortunately all these hacks will
  930. surprise users, since users are expecting width() == x and height() == y.  The
  931. one thing you must not do is surprise your users.
  932.  
  933. If it is important to you to retain the "Circle is a kind-of Ellipse"
  934. inheritance relationship, you can weaken the promise made by Ellipse's
  935. setSize(x,y).  E.g., you could change the promise to, "This member function
  936. might set width() to x and/or it might set height() to y, or it might do
  937. nothing".  Unfortunately this dilutes the contract into dribble, since the user
  938. can't rely on any meaningful behavior.  The whole hierarchy therefore begins to
  939. be worthless (it's hard to convince someone to use an object if you have to
  940. shrug your shoulders when asked what the object does for them).
  941.  
  942. (Note: this FAQ has to do with public inheritance; private and protected
  943. inheritance[24] are different.)
  944.  
  945. (Note: setSize(x,y) isn't sacred.  Depending on your goals, it may be okay to
  946. prevent users from changing the dimensions of an Ellipse, in which case it
  947. would be a valid design choice to not have a setSize(x,y) method in Ellipse.
  948. However this series of FAQs discusses what to do when you want to create a
  949. derived class of a pre-existing base class that has an "unacceptable" method in
  950. it.  Of course the ideal situation is to discover this problem when the base
  951. class doesn't yet exist.  But life isn't always ideal...)
  952.  
  953. ==============================================================================
  954.  
  955. [21.8] But I have a Ph.D. in Mathematics, and I'm sure a Circle is a kind of an
  956.        Ellipse! Does this mean Marshall Cline is stupid? Or that C++ is stupid?
  957.        Or that OO is stupid? [UPDATED!]
  958.  
  959. [Recently added a caveat that setSize(x,y) isn't sacred (on 1/97).]
  960.  
  961. Actually, it doesn't mean any of these things.  The sad reality is that it
  962. means your intuition is wrong.
  963.  
  964. Look, I have received and answered dozens of passionate e-mail messages about
  965. this subject.  I have taught it hundreds of times to thousands of software
  966. professionals all over the place.  I know it goes against your intuition.  But
  967. trust me; your intuition is wrong.
  968.  
  969. The real problem is your intuitive notion of "kind of" doesn't match the OO
  970. notion of proper inheritance (technically called "subtyping").  The bottom line
  971. is that the derived class objects must be substitutable for the base class
  972. objects.  In the case of Circle/Ellipse, the setSize(x,y) member function
  973. violates this substitutability.
  974.  
  975. You have three choices: [1] remove the setSize(x,y) member function from
  976. Ellipse (thus breaking existing code that calls the setSize(x,y) member
  977. function), [2] allow a Circle to have a different height than width (an
  978. asymmetrical circle; hmmm), or [3] drop the inheritance relationship.  Sorry,
  979. but there simply are no other choices.  Note that some people mention the
  980. option of deriving both Circle and Ellipse from a third common base class, but
  981. that's just a variant of option [3] above.
  982.  
  983. Another way to say this is that you have to either make the base class weaker
  984. (in this case braindamage Ellipse to the point that you can't set its width and
  985. height to different values), or make the derived class stronger (in this case
  986. empower a Circle with the ability to be both symmetric and, ahem, asymmetric).
  987. When neither of these is very satisfying (such as in the Circle/Ellipse case),
  988. one normally simply removes the inheritance relationship.  If the inheritance
  989. relationship simply has to exist, you may need to remove the mutator member
  990. functions (setHeight(y), setWidth(x), and setSize(x,y)) from the base class.
  991.  
  992. (Note: this FAQ has to do with public inheritance; private and protected
  993. inheritance[24] are different.)
  994.  
  995. (Note: setSize(x,y) isn't sacred.  Depending on your goals, it may be okay to
  996. prevent users from changing the dimensions of an Ellipse, in which case it
  997. would be a valid design choice to not have a setSize(x,y) method in Ellipse.
  998. However this series of FAQs discusses what to do when you want to create a
  999. derived class of a pre-existing base class that has an "unacceptable" method in
  1000. it.  Of course the ideal situation is to discover this problem when the base
  1001. class doesn't yet exist.  But life isn't always ideal...)
  1002.  
  1003. ==============================================================================
  1004.  
  1005. [21.9] But my problem doesn't have anything to do with circles and ellipses, so
  1006.        what good is that silly example to me?
  1007.  
  1008. Ahhh, there's the rub.  You think the Circle/Ellipse example is just a silly
  1009. example.  But in reality, your problem is an isomorphism to that example.
  1010.  
  1011. I don't care what your inheritance problem is, but all (yes all) bad
  1012. inheritances boil down to the Circle-is-not-a-kind-of-Ellipse example.
  1013.  
  1014. Here's why: Bad inheritances always have a base class with an extra capability
  1015. (often an extra member function or two; sometimes an extra promise made by one
  1016. or a combination of member functions) that a derived class can't satisfy.
  1017. You've either got to make the base class weaker, make the derived class
  1018. stronger, or eliminate the proposed inheritance relationship.  I've seen lots
  1019. and lots and lots of these bad inheritance proposals, and believe me, they all
  1020. boil down to the Circle/Ellipse example.
  1021.  
  1022. Therefore, if you truly understand the Circle/Ellipse example, you'll be able
  1023. to recognize bad inheritance everywhere.  If you don't understand what's going
  1024. on with the Circle/Ellipse problem, the chances are high that you'll make some
  1025. very serious and very expensive inheritance mistakes.
  1026.  
  1027. Sad but true.
  1028.  
  1029. (Note: this FAQ has to do with public inheritance; private and protected
  1030. inheritance[24] are different.)
  1031.  
  1032. ==============================================================================
  1033.  
  1034. SECTION [22]: Inheritance -- abstract base classes (ABCs)
  1035.  
  1036.  
  1037. [22.1] What's the big deal of separating interface from implementation?
  1038.  
  1039. Interfaces are a company's most valuable resources.  Designing an interface
  1040. takes longer than whipping together a concrete class which fulfills that
  1041. interface.  Furthermore interfaces require the time of more expensive people.
  1042.  
  1043. Since interfaces are so valuable, they should be protected from being tarnished
  1044. by data structures and other implementation artifacts.  Thus you should
  1045. separate interface from implementation.
  1046.  
  1047. ==============================================================================
  1048.  
  1049. [22.2] How do I separate interface from implementation in C++ (like Modula-2)?
  1050.  
  1051. Use an ABC[22.3].
  1052.  
  1053. ==============================================================================
  1054.  
  1055. [22.3] What is an ABC?
  1056.  
  1057. An abstract base class.
  1058.  
  1059. At the design level, an abstract base class (ABC) corresponds to an abstract
  1060. concept.  If you asked a mechanic if he repaired vehicles, he'd probably wonder
  1061. what kind-of vehicle you had in mind.  Chances are he doesn't repair space
  1062. shuttles, ocean liners, bicycles, or nuclear submarines.  The problem is that
  1063. the term "vehicle" is an abstract concept (e.g., you can't build a "vehicle"
  1064. unless you know what kind of vehicle to build).  In C++, class Vehicle would be
  1065. an ABC, with Bicycle, SpaceShuttle, etc, being subclasses (an OceanLiner
  1066. is-a-kind-of-a Vehicle).  In real-world OO, ABCs show up all over the place.
  1067.  
  1068. At the programming language level, an ABC is a class that has one or more pure
  1069. virtual[22.4] member functions.  You cannot make an object (instance) of an
  1070. ABC.
  1071.  
  1072. ==============================================================================
  1073.  
  1074. [22.4] What is a "pure virtual" member function?
  1075.  
  1076. A member function declaration that turns a normal class into an abstract class
  1077. (i.e., an ABC).  You normally only implement it in a derived class.
  1078.  
  1079. Some member functions exist in concept; they don't have any reasonable
  1080. definition.  E.g., suppose I asked you to draw a Shape at location (x,y) that
  1081. has size 7.  You'd ask me "what kind of shape should I draw?" (circles,
  1082. squares, hexagons, etc, are drawn differently).  In C++, we must indicate the
  1083. existence of the draw() member function (so users can call it when they have a
  1084. Shape* or a Shape&), but we recognize it can (logically) be defined only in
  1085. subclasses:
  1086.  
  1087.     class Shape {
  1088.     public:
  1089.       virtual void draw() const = 0;  // = 0 means it is "pure virtual"
  1090.       // ...
  1091.     };
  1092.  
  1093. This pure virtual function makes Shape an ABC.  If you want, you can think of
  1094. the "= 0;" syntax as if the code were at the NULL pointer.  Thus Shape promises
  1095. a service to its users, yet Shape isn't able to provide any code to fulfill
  1096. that promise.  This forces any actual object created from a [concrete] class
  1097. derived from Shape to have the indicated member function, even though the base
  1098. class doesn't have enough information to actually define it yet.
  1099.  
  1100. Note that it is possible to provide a definition for a pure virtual function,
  1101. but this usually confuses novices and is best avoided until later.
  1102.  
  1103. ==============================================================================
  1104.  
  1105. [22.5] How do you define a copy constructor or assignment operator for a class
  1106.        that contains a pointer to a (abstract) base class?
  1107.  
  1108. If the class "owns" the object pointed to by the (abstract) base class pointer,
  1109. use the Virtual Constructor Idiom[20.5] in the (abstract) base class.  As usual
  1110. with this idiom, we declare a pure virtual[22.4] clone() method in the base
  1111. class:
  1112.  
  1113.     class Shape {
  1114.     public:
  1115.       // ...
  1116.       virtual Shape* clone() const = 0;   // The Virtual (Copy) Constructor[20.5]
  1117.       // ...
  1118.     };
  1119.  
  1120. Then we implement this clone() method in each derived class:
  1121.  
  1122.     class Circle {
  1123.     public:
  1124.       // ...
  1125.       virtual Shape* clone() const { return new Circle(*this); }
  1126.       // ...
  1127.     };
  1128.  
  1129.     class Square {
  1130.     public:
  1131.       // ...
  1132.       virtual Shape* clone() const { return new Square(*this); }
  1133.       // ...
  1134.     };
  1135.  
  1136. Now suppose that each Fred object "has-a" Shape object.  Naturally the Fred
  1137. object doesn't know whether the Shape is Circle or a Square or ...  Fred's copy
  1138. constructor and assignment operator will invoke Shape's clone() method to copy
  1139. the object:
  1140.  
  1141.     class Fred {
  1142.     public:
  1143.       Fred(Shape* p) : p_(p) { assert(p != NULL); }   // p must not be NULL
  1144.      ~Fred() { delete p; }
  1145.       Fred(const Fred& f) : p_(f.p_->clone()) { }
  1146.       Fred& operator= (const Fred& f)
  1147.         {
  1148.           if (this != &f) {              // Check for self-assignment
  1149.             Shape* p2 = f.p_->clone();   // Create the new one FIRST...
  1150.             delete p_;                   // ...THEN delete the old one
  1151.             p_ = p2;
  1152.           }
  1153.           return *this;
  1154.         }
  1155.       // ...
  1156.     private:
  1157.       Shape* p_;
  1158.     };
  1159.  
  1160. ==============================================================================
  1161.  
  1162. SECTION [23]: Inheritance -- what your mother never told you
  1163.  
  1164.  
  1165. [23.1] When my base class's constructor calls a virtual function, why doesn't
  1166.        my derived class's override of that virtual function get invoked?
  1167.        [UPDATED!]
  1168.  
  1169. [Recently rewrote (on 1/97).]
  1170.  
  1171. During the class Base's constructor, the object isn't yet a Derived, so if
  1172. Base::Base() calls a virtual[20] function virt(), the Base::virt() will be
  1173. invoked, even if Derived::virt() exists.
  1174.  
  1175. Similarly, during Base's destructor, the object is no longer a Derived, so when
  1176. Base::~Base() calls virt(), Base::virt() gets control, not the Derived::virt()
  1177. override.
  1178.  
  1179. You'll quickly see the wisdom of this approach when you imagine the disaster if
  1180. Derived::virt() touched a member object from class Derived.  In particular, if
  1181. Base::Base() called the virtual function virt(), this rule causes Base::virt()
  1182. to be invoked.  If it weren't for this rule, Derived::virt() would get called
  1183. before the Derived part of a Derived object is constructed, and Derived::virt()
  1184. could touch unconstructed member objects from the Derived part of a Derived
  1185. object.  That would be a disaster.
  1186.  
  1187. ==============================================================================
  1188.  
  1189. [23.2] Should a derived class replace ("override") a non-virtual function from
  1190.        a base class?
  1191.  
  1192. It's legal, but it ain't moral.
  1193.  
  1194. Experienced C++ programmers will sometimes redefine a non-virtual function
  1195. (e.g., the derived class implementation might make better use of the derived
  1196. class's resources for efficiency), or to get around the hiding rule[23.3].
  1197. However the client-visible effects must be identical, since non-virtual
  1198. functions are dispatched based on the static type of the pointer/reference
  1199. rather than the dynamic type of the pointed-to/referenced object.
  1200.  
  1201. ==============================================================================
  1202.  
  1203. [23.3] What's the meaning of, Warning: Derived::f(int) hides Base::f(float)?
  1204.  
  1205. It means you're going to die.
  1206.  
  1207. Here's the mess you're in: if Derived declares a member function named f(), and
  1208. Base declares a member function named f() with a different signature (e.g.,
  1209. different parameter types and/or constness), then the Base f() is "hidden"
  1210. rather than "overloaded" or "overridden" (even if the Base f() is virtual[20]).
  1211.  
  1212. Here's how you get out of the mess: Derived must redefine the Base member
  1213. function(s) that are hidden (even if they are non-virtual).  Normally this
  1214. re-definition merely calls the appropriate Base member function.  E.g.,
  1215.  
  1216.     class Base {
  1217.     public:
  1218.       void f(int);
  1219.     };
  1220.  
  1221.     class Derived : public Base {
  1222.     public:
  1223.       void f(double);
  1224.       void f(int i) { Base::f(i); }  // The redefinition merely calls Base::f(int)
  1225.     };
  1226.  
  1227. ==============================================================================
  1228.  
  1229. [23.4] What does it mean that the "virtual table" is an unresolved external?
  1230.  
  1231. If you get a link error of the form
  1232. "Error: Unresolved or undefined symbols detected: virtual table for class Fred,"
  1233. you probably have an undefined virtual[20] member function in class Fred.
  1234.  
  1235. The compiler typically creates a magical data structure called the "virtual
  1236. table" for classes that have virtual functions (this is how it handles dynamic
  1237. binding[20.2]).  Normally you don't have to know about it at all.  But if you
  1238. forget to define a virtual function for class Fred, you will sometimes get this
  1239. linker error.
  1240.  
  1241. Here's the nitty gritty: Many compilers put this magical "virtual table" in the
  1242. compilation unit that defines the first non-inline virtual function in the
  1243. class.  Thus if the first non-inline virtual function in Fred is wilma(), the
  1244. compiler will put Fred's virtual table in the same compilation unit where it
  1245. sees Fred::wilma().  Unfortunately if you accidentally forget to define
  1246. Fred::wilma(), rather than getting a Fred::wilma() is undefined, you may get a
  1247. "Fred's virtual table is undefined".  Sad but true.
  1248.  
  1249. ==============================================================================
  1250.  
  1251.